#!/usr/bin/perl
use DBI;
use Net::Ping;
use Time::HiRes;
use Net::SMTP;
use LWP::UserAgent;

our $serverip;
our $serverport;
our $rrdfilepath; 
our $rrdimgpath;
our $htmlfilepath;
our $mumonitorpath;
our $mumonitorcmdpath;
our $rrdtoolcmd;
our $db_hostname;
our $db_port;
our $db_name;
our $dsn;
our $username;
our $password;
our $SMTP_SERVER;
our $SENDER; 
our $bandwidth_in_mib;
our $bandwidth_out_mib;
our $bandwidth_2_in_mib;
our $bandwidth_2_out_mib;
our $total_swap_mib;
our $avail_swap_mib;
our $total_ram_mib;
our $avail_ram_mib;
our $load_1min_mib;
our $load_5min_mib;
our $load_15min_mib;
our $cpu_user_mib;
our $cpu_system_mib;
our $tcp_connection_mib;
our $update_mib;
our @rrd_name1;
our @rrd_name2;
our @application_list;

if ( -f "/www/mumonitor/monitor/mumonitor.conf") {
        require "/www/mumonitor/monitor/mumonitor.conf";
} else {
        dir("Mumonitor need configuration file not found! .\n");
}

my $monitorhtml = "monitor.htm";
my $tmpfilehtml = "monitor.htm.tmp";
my $ssh_last_name ="Detecting...";

chdir "$mumonitorpath" or die "cannot chdir to $mumonitorpath: $!";

$dbh = DBI->connect($dsn,$username,$password);

$naptime = 60;

for (;;) {
&system_update;
&ping_monitor;
&http_monitor;
&rrdupdate;
&http_create_html;
&ping_create_html;
sleep $naptime;
}

sub system_update{
	open OLD, "<$monitorhtml" or die "can't open $monitorhtml: $!";
	open NEW, ">$tmpfilehtml" or die "can't open $tmpfilehtml: $!";
	while (<OLD>) {
		if ( m/<\!--Current Login User (.*)--><div align=\"left\">(.*)<\/div>/ ) {
			$serverip=$1;
			$current_login_user_status{$serverip} = 1;
			$currentuser_sql = "select currentuser from mu_server where serverip='$serverip'";
			$curr_user = $dbh->selectrow_arrayref("$currentuser_sql");
			print NEW "<\!--Current Login User $serverip--><div align=\"left\">$curr_user->[0]<\/div>\n";
		} elsif ( m/<\!--SSH Lastest Logs (.*)-->(.*)<\/div>/ ) {
			$serverip=$1;
			$sshuser_sql = "select username,clientip,typeid,timestamp from mu_sshmessage where serverip='$serverip' order by timestamp desc limit 10";
			$sth= $dbh->prepare("$sshuser_sql");
			$sth->execute();
			open HTMLFILE, ">$htmlfilepath/$serverip/ssh.html" or die "Cannot create ssh.html: $!";
			print HTMLFILE "<HTML>\n"; 
			print HTMLFILE "<head>\n";
			print HTMLFILE "<title>$serverip ssh log</title>\n";
			print HTMLFILE "</head>\n";
			print HTMLFILE "<body>\n";
			print HTMLFILE "<h1 align=center>$serverip</h1>\n";
			print HTMLFILE "<hr>\n";
			print HTMLFILE "<br>\n";
			my $rows = $sth->fetchall_arrayref();
			print HTMLFILE "<pre>";
			my $ssh_count = 0;
			foreach my $row (@$rows)
			{
			        my ($col1, $col2, $col3, $col4) = @$row;
				if ( $ssh_count =~ 0 ) {
					$ssh_last_name = $col1 ;
				}
				$ssh_count += 1;
			        if ( $col3 =~ 1 ) {
			                print HTMLFILE "<b>$col1</b> has successfully logined from <b>$col2</b> at <b>$col4</b>\n";
			                print HTMLFILE "<br>";
				} else {
			                print HTMLFILE "Error user <b>$col1</b> has denied from <b>$col2</b> at <b>$col4</b>\n";
			                print HTMLFILE "<br>";
				}
			}
			print HTMLFILE "</pre>";
			print HTMLFILE "</body>";
			print HTMLFILE "</html>";
			close HTMLFILE;
			print NEW "<\!--SSH Lastest Logs $serverip--><a href=\"\/html\/$serverip\/ssh.html\"><div align=\"left\">$ssh_last_name<\/div>\n";
		} elsif ( m/<\!--Server Started Time (.*)--><div align=\"left\">(.*)<\/div>/){
			$serverip=$1;
			$server_started_time{$serverip} = 1;
			$started_sql="select uptime from mu_server where serverip='$serverip'";	
			$ssh_lastest_log = $dbh->selectrow_arrayref("$started_sql");
			print NEW "<\!--Server Started Time $serverip--><div align=\"left\">$ssh_lastest_log->[0]<\/div>\n";
			$server_started_time = 1;
		}else {
			print NEW "$_";
		}
	}
	rename ($tmpfilehtml, $monitorhtml) or die "cannot rename $tmpfilehtml to $monitorhtml: $!";
	close(OLD) or die "cannot close $monitorhtml: $!";
	close(NEW) or die "cannot close $tmpfilehtml: $!";
}

sub ping_monitor {
	$ping_iplist_sql = "select serverip from mu_monitor_server where monitor_id = '10' or monitor_id = '11'";
	$sth = $dbh->prepare($ping_iplist_sql);
	$sth->execute();
	my $monitor_ping_time=`/bin/date "+%Y-%m-%d %T"`;
	while ($iplist = $sth->fetchrow_array) {
		$p = Net::Ping->new("icmp");
		if ($p->ping($iplist, 2)) {
        	$update_ping_sql="update mu_monitor_server SET ping_detail='ok',monitor_time='$monitor_ping_time' where serverip='$iplist'";
			$dbh->do("$update_ping_sql");
			$error_ping_sql="select serverip from mu_error_message where serverip='$iplist' and flag='0'";
			$error_ping_serverip = $dbh->selectrow_array("$error_ping_sql");
			if ($error_ping_serverip == $iplist){
				$error_recover_time=`/bin/date -d now "+%Y-%m-%d %T"`;
				$dbh->do("update mu_error_message SET flag='1', recover_time='$error_recover_time' where serverip='$iplist' and flag='0' and icmp_message='PING is failure'");
			}
        	open OLD, "<$monitorhtml" or die "can't open $monitorhtml: $!";
	        open NEW, ">$tmpfilehtml" or die "can't open $tmpfilehtml: $!";
	        while (<OLD>) {
				if ( m/<\!--ICMP monitor $iplist--><div align=\"left\">(.*)<\/div>/ ) {
					print NEW "<\!--ICMP monitor $iplist--><div align=\"left\"><a href=\"\/html\/$iplist\/ping.html\">OK<\/a><\/div>\n";
				}else{
					print NEW "$_";
				}
       		}
        	rename ($tmpfilehtml, $monitorhtml) or die "cannot rename $tmpfilehtml to $monitorhtml: $!";
        	close(NEW) or die "cannot close $tmpfilehtml: $!";
	        close(OLD) or die "cannot close $monitorhtml: $!";
		}else{
        	$update_ping_sql="update mu_monitor_server SET ping_detail='fail',monitor_time='$monitor_ping_time' where serverip='$iplist'";
			$dbh->do("$update_ping_sql");
			$monitor_id_sql="select monitor_id from mu_monitor_server where serverip='$iplist'";
			$monitor_id_show=$dbh->selectrow_array("$monitor_id_sql");
			$error_ping_sql="select serverip from mu_error_message where serverip='$iplist' and flag='0' and icmp_message='PING is failure'";
			$error_ping_serverip = $dbh->selectrow_array("$error_ping_sql");
			$error_time=`/bin/date "+%Y-%m-%d %T"`;
			if ($error_ping_serverip == "") {
				$dbh->do("INSERT INTO mu_error_message VALUES ('$iplist','$monitor_id_show','$error_time','0','PING is failure','','0')");
			}elsif ($error_ping_serverip != $iplist) {
	       	 	$dbh->do("INSERT INTO mu_error_message VALUES ('$iplist','$monitor_id_show','$error_time','0','PING is failure','','0')");
			}
        	open OLD, "<$monitorhtml" or die "can't open $monitorhtml: $!";
	        open NEW, ">$tmpfilehtml" or die "can't open $tmpfilehtml: $!";
	        while (<OLD>) {
				if ( m/<\!--ICMP monitor $iplist--><div align=\"left\">(.*)<\/div>/ ) {
					print NEW "<\!--ICMP monitor $iplist--><div align=\"left\"><a href=\"\/html\/$iplist\/ping.html\"><B>Failure</B><\/a><\/div>\n";
				}else{
					print NEW "$_";
				}
       		}
        	rename ($tmpfilehtml, $monitorhtml) or die "cannot rename $tmpfilehtml to $monitorhtml: $!";
        	close(NEW) or die "cannot close $tmpfilehtml: $!";
	        close(OLD) or die "cannot close $monitorhtml: $!";
			$mailbox_sql="select system_admin from mu_server where serverip='$iplist'";
			$mailbox = $dbh->selectrow_array("$mailbox_sql");
			$ping_subject="$monitor_ping_time  $iplist is down. ping is no ack";
			$ping_data="Emerg!!! Please restart your server beacuse icmp is no ack at $monitor_ping_time!!!";
			&send_mail($mailbox,$ping_subject,$ping_data);
		}
        $dbh->do("$update_ping_sql");
        $p->close();
	}
}


sub send_mail{
	my $RECIPIENT = $_[0];
	my $SUBJECT = $_[1];
	my $data = $_[2];
	$mailmsg=Net::SMTP->new($SMTP_SERVER);
	$mailmsg->mail($SENDER);
	$mailmsg->to($RECIPIENT);
	$mailmsg->data();
	$mailmsg->datasend("To: $RECIPIENT\n");
	$mailmsg->datasend("Subject: $SUBJECT\n\n");
	$mailmsg->datasend($data);
	$mailmsg->dataend();
	$mailmsg->quit;
}

sub http_monitor{
	my $response_limit = 12; 
	our @errors;	
    $http_iplist_sql = "select serverip from mu_monitor_server where monitor_id = '01' or monitor_id = '11'";
    $sth = $dbh->prepare($http_iplist_sql);
    $sth->execute();
    my $monitor_http_time=`/bin/date "+%Y-%m-%d %T"`;
    while ($iplist = $sth->fetchrow_array) {
		$url_sql="select monitor_http from mu_monitor_server where serverip='$iplist'";
       	$url = $dbh->selectrow_array("$url_sql");
		&check_url($url);
	}
}

sub check_url {  # subroutine who check given URL
    my $target = $_[0];
    my $ua = LWP::UserAgent->new;
    $ua->agent("$0/0.1 " . $ua->agent);
    my $req = HTTP::Request->new(HEAD => "$target");
    $req->header('Accept' => 'text/html');          #Accept HTML Page
    # send request
    my $start = time;      # Start timer
    my $res = $ua->request($req);
    # check the outcome
    if ($res->is_success) {# Success....all content of page has been received
        my $time = time;     # End timer
		$monitor_http_time=`/bin/date "+%Y-%m-%d %T"`;
        $time = ($time - $start); # Result of timer
		$http_message="OK, Response $time seconds";
		$update_http_sql="update mu_monitor_server SET http_detail='ok',monitor_time='$monitor_http_time' where serverip='$iplist'";
		$dbh->do("$update_http_sql");
		$error_http_sql="select serverip from mu_error_message where serverip='$iplist' and flag='0'";
		$error_http_serverip = $dbh->selectrow_array("$error_http_sql");
		if ($error_http_serverip == $iplist){
			$error_recover_time=`/bin/date "+%Y-%m-%d %T"`;
			$dbh->do("update mu_error_message SET flag='1', recover_time='$monitor_http_time' where serverip='$iplist' and flag='0' and http_message='HTTP is failure'");
		}
		open OLD, "<$monitorhtml" or die "can't open $monitorhtml: $!";
		open NEW, ">$tmpfilehtml" or die "can't open $tmpfilehtml: $!";
		while (<OLD>) {
			if ( m/<\!--HTTP monitor $iplist--><div align=\"left\">(.*)<\/div>/ ) {
				print NEW "<\!--HTTP monitor $iplist--><div align=\"left\"><a href=\"\/html\/$iplist\/http.html\">OK<\/a><\/div>\n";
			}else{
				print NEW "$_";
			}
        }
		rename ($tmpfilehtml, $monitorhtml) or die "cannot rename $tmpfilehtml to $monitorhtml: $!";
		close(NEW) or die "cannot close $tmpfilehtml: $!";
		close(OLD) or die "cannot close $monitorhtml: $!";
	} else {                 # Error .... Site is DOWN and script will send e-mail to you..
		$monitor_http_time=`/bin/date "+%Y-%m-%d %T"`;
		$update_http_sql="update mu_monitor_server SET http_detail='fail',monitor_time='$monitor_http_time' where serverip='$iplist'";
		$dbh->do("$update_http_sql");
		$monitor_id_sql="select monitor_id from mu_monitor_server where serverip='$iplist'";
		$monitor_id_show=$dbh->selectrow_array("$monitor_id_sql");
		$error_http_sql="select serverip from mu_error_message where serverip='$iplist' and flag='0' and http_message='HTTP is failure'";
		$error_http_serverip = $dbh->selectrow_array("$error_http_sql");
		$http_message="Failure";
		if ($error_http_serverip == "") {
			$dbh->do("INSERT INTO mu_error_message VALUES ('$iplist','$monitor_id_show','$monitor_http_time','0','','HTTP is failure','0')");
		}elsif ($error_http_serverip != $iplist) {
			$dbh->do("INSERT INTO mu_error_message VALUES ('$iplist','$monitor_id_show','$monitor_http_time','0','','HTTP is failure','0')");
		}
		open OLD, "<$monitorhtml" or die "can't open $monitorhtml: $!";
		open NEW, ">$tmpfilehtml" or die "can't open $tmpfilehtml: $!";
		while (<OLD>) {
			if ( m/<\!--HTTP monitor $iplist--><div align=\"left\">(.*)<\/div>/ ) {
			print NEW "<\!--HTTP monitor $iplist--><div align=\"left\"><a href=\"\/html\/$iplist\/http.html\"><B>Failure</B><\/a><\/div>\n";
			}else{
				print NEW "$_";
			}
        }
		rename ($tmpfilehtml, $monitorhtml) or die "cannot rename $tmpfilehtml to $monitorhtml: $!";
		close(NEW) or die "cannot close $tmpfilehtml: $!";
		close(OLD) or die "cannot close $monitorhtml: $!";
		$mailbox_sql="select system_admin from mu_server where serverip='$iplist'";
		$mailbox = $dbh->selectrow_array("$mailbox_sql");
		$ping_subject="$monitor_http_time   $iplist http server is down. Please check your http server!";
		$ping_data="Emerg!!! Please restart or check your http service is right!!!";
		&send_mail($mailbox,$ping_subject,$ping_data);
	}

}
sub rrdupdate{
	system("$mumonitorcmdpath/rrdupdate.pl > /dev/null 2> /dev/null");
}

sub http_create_html{
	$ping_iplist_sql = "select serverip from mu_monitor_server where monitor_id = '01' or monitor_id = '11'";
        $sth = $dbh->prepare($ping_iplist_sql);
        $sth->execute();
        my $monitor_ping_time=`/bin/date "+%Y-%m-%d %T"`;
        while ($iplist = $sth->fetchrow_array) {
                $httpd_sql = "select error_time,recover_time from mu_error_message where http_message='HTTP is failure' and serverip='$iplist' order by error_time desc limit 50;";
                $sth1= $dbh->prepare("$httpd_sql");
                $sth1->execute();
                my $rows = $sth1->fetchall_arrayref();
                open HTMLFILE, "> $htmlfilepath$iplist/http.html" or die "Cannot create http.html: $!";
                select HTMLFILE;
                print "<HTML>\n";
                print "<head>\n";
                print "<title>$iplist HTTP Application log</title>\n";
                print "</head>\n";
                print "<body>\n";
                print "<h1 align=center>$iplist</h1>\n";
                print "<hr>\n";
                print "<br>\n";
                foreach my $row (@$rows) {
                        my ($col1, $col2) = @$row;
                        print "<pre>";
                        print "HTTP Application down at <b>$col1</b> and restart at <b>$col2</b>\n";
                }
                print "</pre>";
                print "</body>";
                print "</html>";
                close HTMLFILE;
        }
}

sub ping_create_html{
	$ping_iplist_sql = "select serverip from mu_monitor_server where monitor_id = '10' or monitor_id = '11'";
        $sth = $dbh->prepare($ping_iplist_sql);
        $sth->execute();
        my $monitor_ping_time=`/bin/date "+%Y-%m-%d %T"`;
        while ($iplist = $sth->fetchrow_array) {
                $ping_sql = "select error_time,recover_time from mu_error_message where http_message=' PING is failure' and serverip='$iplist' order by error_time desc limit 50;";
                $sth1= $dbh->prepare("$ping_sql");
                $sth1->execute();
                my $rows = $sth1->fetchall_arrayref();
                open HTMLFILE, ">$htmlfilepath$iplist/ping.html" or die "Cannot create ping.html: $!";
                select HTMLFILE;
                print "<HTML>\n";
                print "<head>\n";
                print "<title>$iplist Server restart log</title>\n";
                print "</head>\n";
                print "<body>\n";
                print "<h1 align=center>$iplist</h1>\n";
                print "<hr>\n";
                print "<br>\n";
                foreach my $row (@$rows) {
                        my ($col1, $col2) = @$row;
                        print "<pre>";
                        print "Server down at <b>$col1</b> and restart at <b>$col2</b>\n";
                }
                print "</pre>";
                print "</body>";
                print "</html>";
                close HTMLFILE;
        }
}

$dbh->disconnect;
